package yartiss.engine.simulation;

import java.util.HashMap;
import java.util.Map;

import yartiss.engine.simulation.events.EventGenerator;
import yartiss.engine.simulation.events.IEventVisitor;
import yartiss.engine.simulation.system.ITask;

public abstract class Event {

	public static long Undefined = Long.MIN_VALUE;//Long.MIN_VALUE;
	public static String SlackEnergy 	= "SlackEnergy";
	public static String SlackTime 	= "SlackTime";
	public static String EnergyLevel 	= "EnergyLevel";
	
	protected final long date;
	protected  Map<String, Long> metrics = new HashMap<String, Long>();
	
	protected final ITask task;
	private final EventGenerator eventGenerator;
	private final int procId;

	protected Event(ITask task,int procId, long date, Map<String, Long> metrics, EventGenerator eventGenerator){
		this.procId = procId;
		this.date = date;
		this.task = task;
		this.eventGenerator = eventGenerator;
		if(metrics!=null) 
			this.metrics.putAll(metrics);
	}
	
	public  long getDate() {
		return date;
	}
	
	public ITask getTask(){
		return task;
	}
	
	public void setMetric(String metricName, long value){
		metrics.put(metricName, value);
	}
	
	public long getMetric(String metricName){
		if(!metrics.containsKey(metricName))
			return Undefined;
			//throw new IllegalArgumentException(this+" : "+metricName+" : not found metric");
		return metrics.get(metricName);
	}
	
	/**
	 * @return the metrics
	 */
	public Map<String, Long> getMetrics() {
		return metrics;
	}

	/**
	 * @param metrics the metrics to set
	 */
	public void setMetrics(Map<String, Long> metrics) {
		if(metrics != null)
			this.metrics.putAll(metrics);
	}
	
	/**
	 * @return the eventGenerator
	 */
	public EventGenerator getEventGenerator() {
		return eventGenerator;
	}

	abstract public String toString() ;

	public abstract void accept(IEventVisitor visitor);
	

	
	public void actionPerformed(long date) {
		
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (date ^ (date >>> 32));
		result = prime * result + ((task == null) ? 0 : task.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Event other = (Event) obj;
		if (date != other.date)
			return false;
		if (metrics.get(EnergyLevel) != other.getMetric(EnergyLevel))
			return false;
		if (task == null) {
			if (other.task != null)
				return false;
		} else if (!task.equals(other.task))
			return false;
		return true;
	}

	/**
	 * @return the procId
	 */
	public int getProcId() {
		return procId;
	}

	
	
	

}
